package com.uw.uwconfig.server.cluster;

import lombok.Getter;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.atomic.AtomicBoolean;

public class Election {

    private final DataSource dataSource;

    public Election(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    private Connection connection;

    @Getter
    private final AtomicBoolean lock = new AtomicBoolean(false);


    /**
     * 方案一：各个节点根据相同算法选主，保障每个节点有一致的信息，选主结果一致。 => 参考 uw-registry 实现
     * 方案二：外部有一个分布式锁，谁拿到锁谁是主。 => 参考 uw-config 实现
     * 方案三：分布式一致性算法， raft, paxos。
     */
    public void lock() {
        try {
            doLock();
            lock.set(true);
        } catch (Exception e) {
            lock.set(false);
        }
    }

    private void doLock() throws SQLException {
        connection.setAutoCommit(false);
        connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
        connection.createStatement().execute("set innodb_lock_wait_timeout=5");
        connection.createStatement().execute("select id from locks where id = 1 for update ");

        if (lock.get()) {
            System.out.println(" ==>>>> reenter this dist lock.");
        } else {
            System.out.println(" ==>>>> get a dist lock.");
            // 重新加载一下数据库的数据
        }

    }


    public void init() {
        try {
            connection = dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public void destroy() {
        try {
            if (connection != null && !connection.isClosed()) {
                connection.rollback();
                connection.close();

            }
        } catch (SQLException e) {
            System.out.println("ignore this close exception in DistributedLocks.destroy");
        }
    }


}
